#include "aht20.h"


bool AHT20_getBit(int NUM, int n);
void AHT20_check(void);
void AHT20_measures(void);
void AHT20_readData(float *tem, float *hum);

AHT20ClassStruct AHT20Class = {
    .init = AHT20_init,
    .check = AHT20_check,
    .measures = AHT20_measures,
    .read = AHT20_readData
};

// AHT20 IIC端口定义
#define AHT20_IIC_SDA   GPIO_NUM_26
#define AHT20_IIC_SCL   GPIO_NUM_25
#define AHT20_IIC_NUM   I2C_NUM_1

#define AHT20_addr 0x38

static const char *TAG = "AHT20";

bool AHT20_getBit(int NUM, int n)
{
    if(NUM &(1<<n)){return true;}
    else {return false;}
}

void AHT20_check(void)
{
    uint8_t status_byte[1] = {0};
    i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
    i2c_master_start(cmd_handle); //0x71
    i2c_master_write_byte(cmd_handle, (AHT20_addr << 1 | I2C_MASTER_READ), true ); //send 0x71
    i2c_master_read_byte(cmd_handle, status_byte, I2C_MASTER_ACK);
    i2c_master_stop(cmd_handle);
    i2c_master_cmd_begin(AHT20_IIC_NUM, cmd_handle, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd_handle);
    if(!(AHT20_getBit(status_byte[0],3)))
    {
        i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
        i2c_master_start(cmd_handle);
        i2c_master_write_byte(cmd_handle, (AHT20_addr << 1 | I2C_MASTER_WRITE), true );
        i2c_master_write_byte(cmd_handle, (0xbe), true);
        i2c_master_write_byte(cmd_handle, (0x08), true);
        i2c_master_write_byte(cmd_handle, (0x00), true);
        i2c_master_stop(cmd_handle);
        i2c_master_cmd_begin(AHT20_IIC_NUM, cmd_handle, 1000 / portTICK_PERIOD_MS);
        i2c_cmd_link_delete(cmd_handle);
    }
    ESP_LOGI(TAG, "status %u\n", (uint8_t)status_byte[0]);

    vTaskDelay(100 / portTICK_PERIOD_MS);
}

void AHT20_measures(void)
{
     i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
     i2c_master_start(cmd_handle); //0x71
     i2c_master_write_byte(cmd_handle, (AHT20_addr << 1 | I2C_MASTER_WRITE), true);
     i2c_master_write_byte(cmd_handle, (0xac), true );
     i2c_master_write_byte(cmd_handle, (0x33), true );
     i2c_master_write_byte(cmd_handle, (0x00), true );
     i2c_master_stop(cmd_handle);
     i2c_master_cmd_begin(AHT20_IIC_NUM, cmd_handle, 800 / portTICK_PERIOD_MS);
     i2c_cmd_link_delete(cmd_handle);
}

void AHT20_readData(float *tem, float *hum)
{
    uint8_t data[7]= {0,0,0,0,0,0,0};
    i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
    i2c_master_start(cmd_handle);
    i2c_master_write_byte(cmd_handle, (AHT20_addr << 1 | I2C_MASTER_READ), true );
    i2c_master_read(cmd_handle, data, 7, I2C_MASTER_ACK);
    i2c_master_stop(cmd_handle);
    i2c_master_cmd_begin(AHT20_IIC_NUM, cmd_handle, 800 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd_handle);

    uint32_t rh = (((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (data[3])) >> 4;
    uint32_t temp = ((uint32_t)(data[3] & 0x0F) << 16) | ((uint32_t)data[4] << 8) | (uint32_t)data[5];

    *tem = (temp *(0.00019073F) - 50);
    *hum = (rh * (0.0000953674316F));
}

void AHT20_run_task(void *ignore){

    while(1){
        AHT20_measures();
        AHT20_readData(&AHT20Class.temperature, &AHT20Class.humidity);
        printf("AHT20: Temperature: %3.1f , Humidity: %3.1f\n", AHT20Class.temperature, AHT20Class.humidity);
    
        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
}

void AHT20_init(void)
{
    vTaskDelay(5000 / portTICK_PERIOD_MS);

    i2c_config_t AHT20_IIC_config = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = AHT20_IIC_SDA,
        .scl_io_num = AHT20_IIC_SCL,
        .sda_pullup_en = GPIO_PULLUP_DISABLE,
        .scl_pullup_en = GPIO_PULLUP_DISABLE,
        .master.clk_speed = 100000
    };

    i2c_param_config(AHT20_IIC_NUM, &AHT20_IIC_config);
    i2c_driver_install(AHT20_IIC_NUM, AHT20_IIC_config.mode, 0, 0, 0);

    AHT20_check();

    ESP_LOGI(TAG, "AHT20 init complate");

    xTaskCreate(&AHT20_run_task, "task_read_ath20", 2048, NULL, 0, NULL);
}
